Skip to content

Conversation

@kasuga-fj
Copy link
Contributor

@kasuga-fj kasuga-fj commented Nov 28, 2025

Add two test cases where dependencies are missed due to overflows. These will be fixed by #169927 and #169928, respectively.

Copy link
Contributor Author

kasuga-fj commented Nov 28, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

Comment on lines +161 to +162
%guard = icmp ne i64 %const, 0
br i1 %guard, label %loop, label %exit
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a hack to transfer the nsw flag of 3 * %m from IR to SCEV. Please let me know if there is a better way to do this.

@kasuga-fj kasuga-fj marked this pull request as ready for review November 29, 2025 01:31
@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Nov 29, 2025
@kasuga-fj kasuga-fj changed the title [DA] Add tests for GCD MIV misses dependency due to overflow [DA] Add tests for GCD MIV misses dependency due to overflow (NFC) Nov 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 29, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Ryotaro Kasuga (kasuga-fj)

Changes

Add two test cases where dependencies are missed due to overflows. These will be fixed by #169927 and #169928, respectively.


Full diff: https://github.com/llvm/llvm-project/pull/169926.diff

1 Files Affected:

  • (modified) llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll (+119)
diff --git a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
index 9169ac323d834..618d14c75faad 100644
--- a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
@@ -56,6 +56,125 @@ loop:
   %ec = icmp eq i64 %i.inc, 100
   br i1 %ec, label %exit, label %loop
 
+exit:
+  ret void
+}
+
+; max_i = INT64_MAX/6  // 1537228672809129301
+; for (long long i = 0; i <= max_i; i++) {
+;   A[-6*i + INT64_MAX] = 0;
+;   if (i)
+;     A[3*i - 2] = 1;
+; }
+;
+; FIXME: DependenceAnalysis currently detects no dependency between the two
+; stores, but it does exist. For example,
+;
+;  memory access       | i == 1 | i == (max_i + 1) / 2 | i == max_i
+; ---------------------|--------|----------------------|-------------------
+;  A[-6*i + INT64_MAX] |        | A[3*max_i - 2]       | A[1]
+;  A[3*i - 2]          | A[1]   |                      | A[3*max_i - 2]
+;
+;
+define void @gcdmiv_delta_ovfl(ptr %A) {
+; CHECK-ALL-LABEL: 'gcdmiv_delta_ovfl'
+; CHECK-ALL-NEXT:  Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
+; CHECK-ALL-NEXT:    da analyze - none!
+; CHECK-ALL-NEXT:  Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-ALL-NEXT:    da analyze - none!
+; CHECK-ALL-NEXT:  Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-ALL-NEXT:    da analyze - none!
+;
+; CHECK-GCD-MIV-LABEL: 'gcdmiv_delta_ovfl'
+; CHECK-GCD-MIV-NEXT:  Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
+; CHECK-GCD-MIV-NEXT:    da analyze - consistent output [*]!
+; CHECK-GCD-MIV-NEXT:  Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-GCD-MIV-NEXT:    da analyze - none!
+; CHECK-GCD-MIV-NEXT:  Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-GCD-MIV-NEXT:    da analyze - consistent output [*]!
+;
+entry:
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.latch ]
+  %subscript.0 = phi i64 [ 9223372036854775807, %entry ], [ %subscript.0.next, %loop.latch ]
+  %subscript.1 = phi i64 [ -2, %entry ], [ %subscript.1.next, %loop.latch ]
+  %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0
+  store i8 0, ptr %idx.0
+  %cond.store = icmp ne i64 %i, 0
+  br i1 %cond.store, label %if.store, label %loop.latch
+
+if.store:
+  %idx.1 = getelementptr i8, ptr %A, i64 %subscript.1
+  store i8 1, ptr %idx.1
+  br label %loop.latch
+
+loop.latch:
+  %i.inc = add nuw nsw i64 %i, 1
+  %subscript.0.next = add nsw i64 %subscript.0, -6
+  %subscript.1.next = add nsw i64 %subscript.1, 3
+  %exitcond = icmp sgt i64 %i.inc, 1537228672809129301
+  br i1 %exitcond, label %exit, label %loop.header
+
+exit:
+  ret void
+}
+
+; max_i = INT64_MAX/3  // 3074457345618258602
+; for (i = 0; i < max_i; i++) {
+;   A[3*i] = 0;
+;   A[-3*i - 3*m - INT64_MAX] = 1;
+; }
+;
+; FIXME: DependenceAnalysis currently detects no dependency between the two
+; stores, but it may exist. For example, consider `m = 1`. Then,
+; `-3*m - INT64_MAX` is `INT64_MAX - 1`. So `-3*i - 3*m - INT64_MAX` is
+; effectively `-3*i + (INT64_MAX - 1)`. Thus, accesses will be as follows:
+;
+;  memory access             | i == 1           | i == max_i - 1
+; ---------------------------|------------------|------------------
+;  A[3*i]                    | A[3]             | A[INT64_MAX - 4]
+;  A[-3*i - 3*m - INT64_MAX] | A[INT64_MAX - 4] | A[3]
+;
+
+define void @gcdmiv_const_ovfl(ptr %A, i64 %m) {
+; CHECK-ALL-LABEL: 'gcdmiv_const_ovfl'
+; CHECK-ALL-NEXT:  Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
+; CHECK-ALL-NEXT:    da analyze - none!
+; CHECK-ALL-NEXT:  Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-ALL-NEXT:    da analyze - none!
+; CHECK-ALL-NEXT:  Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-ALL-NEXT:    da analyze - none!
+;
+; CHECK-GCD-MIV-LABEL: 'gcdmiv_const_ovfl'
+; CHECK-GCD-MIV-NEXT:  Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
+; CHECK-GCD-MIV-NEXT:    da analyze - consistent output [*]!
+; CHECK-GCD-MIV-NEXT:  Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-GCD-MIV-NEXT:    da analyze - none!
+; CHECK-GCD-MIV-NEXT:  Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-GCD-MIV-NEXT:    da analyze - consistent output [*]!
+;
+entry:
+  %m.3 = mul nsw i64 -3, %m
+  %const = sub i64 %m.3, 9223372036854775807
+  %guard = icmp ne i64 %const, 0
+  br i1 %guard, label %loop, label %exit
+
+loop:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ]
+  %offset.0 = phi i64 [ 0, %entry ], [ %offset.0.next, %loop ]
+  %offset.1 = phi i64 [ %const, %entry ], [ %offset.1.next, %loop ]
+  %gep.0 = getelementptr inbounds i8, ptr %A, i64 %offset.0
+  %gep.1 = getelementptr inbounds i8, ptr %A, i64 %offset.1
+  store i8 0, ptr %gep.0
+  store i8 1, ptr %gep.1
+  %i.inc = add nuw nsw i64 %i, 1
+  %offset.0.next = add nsw i64 %offset.0, 3
+  %offset.1.next = add nsw i64 %offset.1, -3
+  %ec = icmp eq i64 %i.inc, 3074457345618258602
+  br i1 %ec, label %exit, label %loop
+
 exit:
   ret void
 }

Copy link
Member

@Meinersbur Meinersbur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kasuga-fj kasuga-fj merged commit d431f38 into main Dec 1, 2025
14 checks passed
@kasuga-fj kasuga-fj deleted the users/kasuga-fj/da-gcdmiv-delta-overflow-test branch December 1, 2025 13:36
aahrun pushed a commit to aahrun/llvm-project that referenced this pull request Dec 1, 2025
…lvm#169926)

Add two test cases where dependencies are missed due to overflows. These
will be fixed by llvm#169927 and llvm#169928, respectively.
kasuga-fj added a commit that referenced this pull request Dec 1, 2025
Add overflow check when computing `Delta` in `gcdMIVtest`.

Fix one of the tests added by #169926.
kasuga-fj added a commit that referenced this pull request Dec 1, 2025
In `gcdMIVtest`, there is logic that assumes the addition(s) of
`SCEVAddExpr` don't overflow without any checks. Adding overflow checks
would be fine, but this part appeart to be less useful. So this patch
removes it.

Fix one of the tests added in #169926.
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Dec 3, 2025
…lvm#169926)

Add two test cases where dependencies are missed due to overflows. These
will be fixed by llvm#169927 and llvm#169928, respectively.
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Dec 3, 2025
Add overflow check when computing `Delta` in `gcdMIVtest`.

Fix one of the tests added by llvm#169926.
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Dec 3, 2025
In `gcdMIVtest`, there is logic that assumes the addition(s) of
`SCEVAddExpr` don't overflow without any checks. Adding overflow checks
would be fine, but this part appeart to be less useful. So this patch
removes it.

Fix one of the tests added in llvm#169926.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:analysis Includes value tracking, cost tables and constant folding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants